package cn.com.anysdk.starter.aspect;

import cn.com.anysdk.core.log.OperationLogger;
import cn.com.anysdk.starter.config.oss.OssLoggingConfiguration;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class OssLoggingAspect {
    private final OssLoggingConfiguration loggingConfig;

    @Around("execution(* cn.com.anysdk.oss.api.IOssService.*(..))")
    public Object logOssOperation(ProceedingJoinPoint joinPoint) throws Throwable {
        if (!loggingConfig.isEnabled()) {
            return joinPoint.proceed();
        }

        String methodName = joinPoint.getSignature().getName();
        String provider = getProvider(joinPoint.getTarget());
        String path = getPath(joinPoint.getArgs());
        long startTime = System.currentTimeMillis();
        String requestId = generateRequestId();

        try {
            // 记录操作开始
            OperationLogger.logOperationStart(methodName, provider, path);

            // 执行操作
            Object result = joinPoint.proceed();

            // 记录操作结束
            long duration = System.currentTimeMillis() - startTime;
            long fileSize = getFileSize(joinPoint.getArgs());
            boolean isPrivate = isPrivateOperation(methodName);
            OperationLogger.logOperationEnd(duration, fileSize, isPrivate, requestId);

            return result;
        } catch (Throwable e) {
            // 记录操作错误
            OperationLogger.logOperationError(e.getMessage(), e);
            throw e;
        }
    }

    private String getProvider(Object target) {
        String className = target.getClass().getSimpleName().toLowerCase();
        if (className.contains("aliyun")) {
            return "aliyun";
        } else if (className.contains("local")) {
            return "local";
        }
        return "unknown";
    }

    private String getPath(Object[] args) {
        if (args != null && args.length > 0 && args[0] instanceof String) {
            return (String) args[0];
        }
        return "unknown";
    }

    private long getFileSize(Object[] args) {
        if (args != null) {
            for (Object arg : args) {
                if (arg instanceof java.io.File) {
                    return ((java.io.File) arg).length();
                } else if (arg instanceof byte[]) {
                    return ((byte[]) arg).length;
                }
            }
        }
        return 0L;
    }

    private boolean isPrivateOperation(String methodName) {
        return methodName.contains("private") || methodName.contains("signed");
    }

    private String generateRequestId() {
        return java.util.UUID.randomUUID().toString();
    }
}